package cn.udrm.water.base.v1.waterdelivery.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.udrm.water.base.v1.commons.models.PageModel;
import cn.udrm.water.base.v1.waterdelivery.dto.CanalSystemDto;
import cn.udrm.water.base.v1.waterdelivery.dto.InvertedSiphonDto;
import cn.udrm.water.base.v1.waterdelivery.dto.InvertedSiphonDtoMapper;
import cn.udrm.water.base.v1.waterdelivery.entities.CanalSystem;
import cn.udrm.water.base.v1.waterdelivery.entities.InvertedSiphon;
import cn.udrm.water.base.v1.waterdelivery.repository.InvertedSiphonRepository;

@Service
@Transactional(readOnly=true)
public class InvertedSiphonService {

	@Autowired
	private InvertedSiphonRepository invertedSiphonRepository;
	@Autowired
	private InvertedSiphonDtoMapper invertedSiphonDtoMapper;
	@Autowired
	private CanalSystemService canalSystemService;
	
	/**
	 * 分页条件查询
	 * @param pageNumberStr
	 * @param pageSizeStr
	 * @param waterGateSearch
	 * @param sortField
	 * @param sortType
	 * @return
	 */
	public PageModel<InvertedSiphonDto> getPageByConditions(String pageNumberStr, String pageSizeStr, final InvertedSiphonDto invertedSiphonSearch
			, String sortField, String sortType) {
		int number = 0,
			size = 0;
		try {
			number = Integer.parseInt(pageNumberStr);
		} catch (Exception e) {}
		try {
			size = Integer.parseInt(pageSizeStr);
		} catch (Exception e) {}
		size = size == 0 ? 10 : size;
		Sort sort = null;
		if (!StringUtils.isEmpty(sortField)) {
			try {
				sort = new Sort(StringUtils.isEmpty(sortType) ? Direction.ASC : (sortType.equals("ASC")) ? Direction.ASC : Direction.DESC, sortField);
			} catch (Exception e) {}
		} else {
			sort = new Sort(Direction.ASC, "createDate");
		}
		Pageable pageable = PageRequest.of(number, size, sort);
		Specification<InvertedSiphon> specification = new Specification<InvertedSiphon>() {
			private static final long serialVersionUID = 1L;

			@Override
			public Predicate toPredicate(Root<InvertedSiphon> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicates = new ArrayList<>();
				
				if (predicates.size() == 0) {
					return null;
				}
				Predicate predicateArr[] = new Predicate[predicates.size()];
				return cb.and(predicates.toArray(predicateArr));
			}
		};
		Page<InvertedSiphon> page = invertedSiphonRepository.findAll(specification, pageable);
		List<InvertedSiphon> content = page.getContent();
		List<InvertedSiphonDto> dtos = invertedSiphonDtoMapper.from(content);
		PageModel<InvertedSiphonDto> pageModel = new PageModel<InvertedSiphonDto>(page.getSize(), page.getNumber(), page.getTotalElements(), dtos);
		return pageModel;
	}
	
	public InvertedSiphonDto getAllById(String id) {
		InvertedSiphon invertedSiphon = invertedSiphonRepository.findAllById(id);
		InvertedSiphonDto invertedSiphonDto = invertedSiphonDtoMapper.from(invertedSiphon);
		return invertedSiphonDto;
	}
	
	@Transactional(readOnly=false)
	public InvertedSiphonDto save(InvertedSiphonDto invertedSiphonDto) {
		InvertedSiphon invertedSiphon = invertedSiphonDtoMapper.fromInvertedSiphonDto(invertedSiphonDto);
		invertedSiphon.setId(null);
		invertedSiphon.setCreateDate(new Date());
		/*
		 * 添加渠道
		 */
		String canalSystemGuid = invertedSiphonDto.getCanalSystemGuid();
		CanalSystemDto canalSystemDto = null;
		if (StringUtils.isNotBlank(canalSystemGuid)) {
			canalSystemDto = canalSystemService.getSelfById(canalSystemGuid);
		}
		if (canalSystemDto != null) {
			invertedSiphon.setCanalSystem(new CanalSystem(canalSystemDto.getId()));
		}
		invertedSiphon = invertedSiphonRepository.saveAndFlush(invertedSiphon);
		InvertedSiphonDto dto = invertedSiphonDtoMapper.from(invertedSiphon);
		return dto;
	}
	@Transactional(readOnly=false)
	public InvertedSiphonDto update(InvertedSiphonDto invertedSiphonDto) {
		InvertedSiphon invertedSiphon = invertedSiphonDtoMapper.fromInvertedSiphonDto(invertedSiphonDto);
		/*
		 * 添加渠道
		 */
		String canalSystemGuid = invertedSiphonDto.getCanalSystemGuid();
		CanalSystemDto canalSystemDto = null;
		if (StringUtils.isNotBlank(canalSystemGuid)) {
			canalSystemDto = canalSystemService.getSelfById(canalSystemGuid);
		}
		if (canalSystemDto != null) {
			invertedSiphon.setCanalSystem(new CanalSystem(canalSystemDto.getId()));
		}
		invertedSiphon = invertedSiphonRepository.saveAndFlush(invertedSiphon);
		InvertedSiphonDto dto = invertedSiphonDtoMapper.from(invertedSiphon);
		return dto;
	}
	
	@Transactional(readOnly=false)
	public void deleteAllSelf(String[] ids) {
		if (ids == null || ids.length == 0) {
			return;
		}
		for (String id : ids) {
			invertedSiphonRepository.deleteById(id);
		}
	}
	
	@Transactional(readOnly=false)
	public void deleteAll(String[] ids) {
		if (ids == null || ids.length == 0) {
			return;
		}
		List<InvertedSiphon> invertedSiphons = new ArrayList<InvertedSiphon>();
		for (String id : ids) {
			invertedSiphons.add(new InvertedSiphon(id));
		}
		this.deleteAll(invertedSiphons);
	}
	
	@Transactional(readOnly=false)
	public void deleteAll(Iterable<InvertedSiphon> iterable) {
		if (iterable == null || iterable.iterator() == null) {
			return;
		}
		Iterator<InvertedSiphon> iterator = iterable.iterator();
		while (iterator.hasNext()) {
			InvertedSiphon invertedSiphon = iterator.next();
			invertedSiphonRepository.delete(invertedSiphon);
		}
	}
}
